React Context Provider ํจํด์ ํ์ฉํ์ฌ ์ํ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌํ๊ณ , ์ฑ๋ฅ์ ์ต์ ํํ๋ฉฐ, ๋ถํ์ํ ์ฌ๋ ๋๋ง์ ๋ฐฉ์งํ์ธ์.
React Context Provider ํจํด: ์ฑ๋ฅ ์ต์ ํ ๋ฐ ์ฌ๋ ๋๋ง ๋ฌธ์ ๋ฐฉ์ง
React Context API๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ ์ญ ์ํ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํ ๊ฐ๋ ฅํ ๋๊ตฌ์ ๋๋ค. props๋ฅผ ๋งค๋ฒ ์๋์ผ๋ก ์ ๋ฌํ์ง ์๊ณ ๋ ์ปดํฌ๋ํธ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ Context๋ฅผ ์๋ชป ์ฌ์ฉํ๋ฉด ์ฑ๋ฅ ๋ฌธ์ , ํนํ ๋ถํ์ํ ์ฌ๋ ๋๋ง์ผ๋ก ์ด์ด์ง ์ ์์ต๋๋ค. ์ด ๊ธ์์๋ ์ฑ๋ฅ์ ์ต์ ํํ๊ณ ์ด๋ฌํ ํจ์ ์ ํผํ๋ ๋ฐ ๋์์ด ๋๋ ๋ค์ํ Context Provider ํจํด์ ์ดํด๋ด ๋๋ค.
๋ฌธ์ ์ดํด: ๋ถํ์ํ ์ฌ๋ ๋๋ง
๊ธฐ๋ณธ์ ์ผ๋ก Context ๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด ํด๋น Context๋ฅผ ์ฌ์ฉํ๋ ๋ชจ๋ ์ปดํฌ๋ํธ๊ฐ ์ฌ๋ ๋๋ง๋ฉ๋๋ค. ์ด๋ Context์ ๋ณ๊ฒฝ๋ ํน์ ๋ถ๋ถ์ ์์กดํ์ง ์๋ ๊ฒฝ์ฐ์๋ ๋ง์ฐฌ๊ฐ์ง์ ๋๋ค. ์ด๋ ํนํ ํฌ๊ณ ๋ณต์กํ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์๋นํ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ด ๋ ์ ์์ต๋๋ค. ์ฌ์ฉ์ ์ ๋ณด, ํ ๋ง ์ค์ ๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ๊ธฐ๋ณธ ์ค์ ์ ํฌํจํ๋ Context ์๋๋ฆฌ์ค๋ฅผ ๊ณ ๋ คํ์ญ์์ค. ํ ๋ง ์ค์ ๋ง ๋ณ๊ฒฝ๋๋ ๊ฒฝ์ฐ ์ด์์ ์ผ๋ก๋ ํ ๋ง์ ๊ด๋ จ๋ ์ปดํฌ๋ํธ๋ง ์ฌ๋ ๋๋ง๋์ด์ผ ํ๋ฉฐ ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ๋ ๋๋ง๋์ง ์์์ผ ํฉ๋๋ค.
์๋ฅผ ๋ค์ด ์ฌ๋ฌ ๊ตญ๊ฐ์์ ์ก์ธ์คํ ์ ์๋ ๊ธ๋ก๋ฒ ์ ์ ์๊ฑฐ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์๊ฐํด ๋ณด์ญ์์ค. ํตํ ์ ํธ๋๊ฐ ๋ณ๊ฒฝ๋๋ ๊ฒฝ์ฐ(Context ๋ด์์ ์ฒ๋ฆฌ๋จ) ์ ์ฒด ์ ํ ์นดํ๋ก๊ทธ๊ฐ ์ฌ๋ ๋๋ง๋๊ธฐ๋ฅผ ์ํ์ง ์์ผ๋ฉฐ ๊ฐ๊ฒฉ ํ์๋ง ์ ๋ฐ์ดํธํ๋ฉด ๋ฉ๋๋ค.
ํจํด 1: useMemo
๋ฅผ ์ฌ์ฉํ ๊ฐ ๋ฉ๋ชจ์ด์ ์ด์
๋ถํ์ํ ์ฌ๋ ๋๋ง์ ๋ฐฉ์งํ๋ ๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ useMemo
๋ฅผ ์ฌ์ฉํ์ฌ Context ๊ฐ์ ๋ฉ๋ชจ์ด์ ์ด์
ํ๋ ๊ฒ์
๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ข
์์ฑ์ด ๋ณ๊ฒฝ๋ ๋๋ง Context ๊ฐ์ด ๋ณ๊ฒฝ๋ฉ๋๋ค.
์์:
์ฌ์ฉ์ ๋ฐ์ดํฐ์ ์ฌ์ฉ์์ ํ๋กํ์ ์ ๋ฐ์ดํธํ๋ ํจ์๋ฅผ ์ ๊ณตํ๋ `UserContext`๊ฐ ์๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค.
import React, { createContext, useState, useMemo } from 'react';
const UserContext = createContext(null);
function UserProvider({ children }) {
const [user, setUser] = useState({
name: 'John Doe',
email: 'john.doe@example.com',
location: 'New York, USA'
});
const updateUser = (newUserData) => {
setUser(prevState => ({ ...prevState, ...newUserData }));
};
const contextValue = useMemo(() => ({
user,
updateUser,
}), [user, setUser]);
return (
{children}
);
}
export { UserContext, UserProvider };
์ด ์์ ์์ useMemo
๋ `user` ์ํ ๋๋ `setUser` ํจ์๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง `contextValue`๊ฐ ๋ณ๊ฒฝ๋๋๋ก ํฉ๋๋ค. ์๋ฌด๊ฒ๋ ๋ณ๊ฒฝ๋์ง ์์ผ๋ฉด `UserContext`๋ฅผ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ๋ ์ฌ๋ ๋๋ง๋์ง ์์ต๋๋ค.
์ฅ์ :
- ๊ตฌํ์ด ๊ฐ๋จํฉ๋๋ค.
- Context ๊ฐ์ด ์ค์ ๋ก ๋ณ๊ฒฝ๋์ง ์์ ๋ ์ฌ๋ ๋๋ง์ ๋ฐฉ์งํฉ๋๋ค.
๋จ์ :
- ์ฌ์ฉ์ ๊ฐ์ฒด์ ์ผ๋ถ๊ฐ ๋ณ๊ฒฝ๋๋ฉด ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ๊ฐ ์ฌ์ฉ์์ ์ด๋ฆ๋ง ํ์ํ๋๋ผ๋ ์ฌ์ ํ ์ฌ๋ ๋๋ง๋ฉ๋๋ค.
- Context ๊ฐ์ ๋ง์ ์ข ์์ฑ์ด ์๋ ๊ฒฝ์ฐ ๊ด๋ฆฌ๊ฐ ๋ณต์กํด์ง ์ ์์ต๋๋ค.
ํจํด 2: ์ฌ๋ฌ Context๋ฅผ ์ฌ์ฉํ ๊ด์ฌ์ฌ ๋ถ๋ฆฌ
๋ ์ธ๋ถํ๋ ์ ๊ทผ ๋ฐฉ์์ Context๋ฅผ ์ฌ๋ฌ ๊ฐ์ ์์ Context๋ก ๋ถํ ํ๋ ๊ฒ์ ๋๋ค. ๊ฐ Context๋ ํน์ ์ํ ๋ถ๋ถ์ ๋ด๋นํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ฌ๋ ๋๋ง ๋ฒ์๊ฐ ์ค์ด๋ค๊ณ ์์กดํ๋ ํน์ ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง ์ปดํฌ๋ํธ๊ฐ ์ฌ๋ ๋๋ง๋ฉ๋๋ค.
์์:
๋จ์ผ `UserContext` ๋์ ์ฌ์ฉ์ ๋ฐ์ดํฐ์ ์ฌ์ฉ์ ๊ธฐ๋ณธ ์ค์ ์ ๋ํ ๋ณ๋์ context๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
import React, { createContext, useState } from 'react';
const UserDataContext = createContext(null);
const UserPreferencesContext = createContext(null);
function UserDataProvider({ children }) {
const [user, setUser] = useState({
name: 'John Doe',
email: 'john.doe@example.com',
location: 'New York, USA'
});
const updateUser = (newUserData) => {
setUser(prevState => ({ ...prevState, ...newUserData }));
};
return (
{children}
);
}
function UserPreferencesProvider({ children }) {
const [theme, setTheme] = useState('light');
const [language, setLanguage] = useState('en');
const toggleTheme = () => {
setTheme(prevTheme => (prevTheme === 'light' ? 'dark' : 'light'));
};
return (
{children}
);
}
export { UserDataContext, UserDataProvider, UserPreferencesContext, UserPreferencesProvider };
์ด์ ์ฌ์ฉ์ ๋ฐ์ดํฐ๋ง ํ์ํ ์ปดํฌ๋ํธ๋ `UserDataContext`๋ฅผ ์ฌ์ฉํ ์ ์๊ณ , ํ ๋ง ์ค์ ๋ง ํ์ํ ์ปดํฌ๋ํธ๋ `UserPreferencesContext`๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ํ ๋ง ๋ณ๊ฒฝ์ผ๋ก ์ธํด `UserDataContext`๋ฅผ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ๊ฐ ๋ ์ด์ ์ฌ๋ ๋๋ง๋์ง ์์ผ๋ฉฐ ๊ทธ ๋ฐ๋์ ๊ฒฝ์ฐ๋ ๋ง์ฐฌ๊ฐ์ง์ ๋๋ค.
์ฅ์ :
- ์ํ ๋ณ๊ฒฝ์ ๊ฒฉ๋ฆฌํ์ฌ ๋ถํ์ํ ์ฌ๋ ๋๋ง์ ์ค์ ๋๋ค.
- ์ฝ๋ ๊ตฌ์ฑ ๋ฐ ์ ์ง ๊ด๋ฆฌ๊ฐ ํฅ์๋ฉ๋๋ค.
๋จ์ :
- ์ฌ๋ฌ ๊ณต๊ธ์์ ํจ๊ป ๋ ๋ณต์กํ ์ปดํฌ๋ํธ ๊ณ์ธต ๊ตฌ์กฐ๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
- Context๋ฅผ ๋ถํ ํ๋ ๋ฐฉ๋ฒ์ ๊ฒฐ์ ํ๋ ค๋ฉด ์ ์คํ ๊ณํ์ด ํ์ํฉ๋๋ค.
ํจํด 3: ์ฌ์ฉ์ ์ง์ ํ ์ ์ฌ์ฉํ ์ ํ๊ธฐ ํจ์
์ด ํจํด์๋ Context ๊ฐ์ ํน์ ๋ถ๋ถ์ ์ถ์ถํ๊ณ ํด๋น ํน์ ๋ถ๋ถ์ด ๋ณ๊ฒฝ๋ ๋๋ง ์ฌ๋ ๋๋ง๋๋ ์ฌ์ฉ์ ์ง์ ํ ์ ๋ง๋๋ ๊ฒ์ด ํฌํจ๋ฉ๋๋ค. ์ด๋ ๋ง์ ์์ฑ์ด ์๋ ํฐ Context ๊ฐ์ด ์์ง๋ง ์ปดํฌ๋ํธ๊ฐ ๊ทธ ์ค ๋ช ๊ฐ์ง๋ง ํ์ํ ๊ฒฝ์ฐ์ ํนํ ์ ์ฉํฉ๋๋ค.
์์:
์๋ `UserContext`๋ฅผ ์ฌ์ฉํ์ฌ ํน์ ์ฌ์ฉ์ ์์ฑ์ ์ ํํ๋ ์ฌ์ฉ์ ์ง์ ํ ์ ๋ง๋ค ์ ์์ต๋๋ค.
import React, { useContext } from 'react';
import { UserContext } from './UserContext'; // UserContext๊ฐ UserContext.js์ ์๋ค๊ณ ๊ฐ์
function useUserName() {
const { user } = useContext(UserContext);
return user.name;
}
function useUserEmail() {
const { user } = useContext(UserContext);
return user.email;
}
export { useUserName, useUserEmail };
์ด์ ์ปดํฌ๋ํธ๋ `useUserName`์ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์์ ์ด๋ฆ์ด ๋ณ๊ฒฝ๋ ๋๋ง ์ฌ๋ ๋๋งํ๊ณ , `useUserEmail`์ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์์ ์ด๋ฉ์ผ์ด ๋ณ๊ฒฝ๋ ๋๋ง ์ฌ๋ ๋๋งํ ์ ์์ต๋๋ค. ๋ค๋ฅธ ์ฌ์ฉ์ ์์ฑ(์: ์์น) ๋ณ๊ฒฝ์ ์ฌ๋ ๋๋ง์ ํธ๋ฆฌ๊ฑฐํ์ง ์์ต๋๋ค.
import React from 'react';
import { useUserName, useUserEmail } from './UserHooks';
function UserProfile() {
const name = useUserName();
const email = useUserEmail();
return (
์ด๋ฆ: {name}
์ด๋ฉ์ผ: {email}
);
}
์ฅ์ :
- ์ฌ๋ ๋๋ง์ ๋ํ ์ธ๋ถํ๋ ์ ์ด.
- Context ๊ฐ์ ํน์ ๋ถ๋ถ๋ง ๊ตฌ๋ ํ์ฌ ๋ถํ์ํ ์ฌ๋ ๋๋ง์ ์ค์ ๋๋ค.
๋จ์ :
- ์ ํํ๋ ค๋ ๊ฐ ์์ฑ์ ๋ํด ์ฌ์ฉ์ ์ง์ ํ ์ ์์ฑํด์ผ ํฉ๋๋ค.
- ์์ฑ์ด ๋ง์ ๊ฒฝ์ฐ ์ฝ๋๊ฐ ๋ ๋ง์์ง ์ ์์ต๋๋ค.
ํจํด 4: React.memo
๋ฅผ ์ฌ์ฉํ ์ปดํฌ๋ํธ ๋ฉ๋ชจ์ด์ ์ด์
React.memo
๋ ํจ์ํ ์ปดํฌ๋ํธ๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์
ํ๋ ๊ณ ์ฐจ ์ปดํฌ๋ํธ(HOC)์
๋๋ค. props๊ฐ ๋ณ๊ฒฝ๋์ง ์์ผ๋ฉด ์ปดํฌ๋ํธ๊ฐ ์ฌ๋ ๋๋ง๋๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค. ์ด๋ฅผ Context์ ๊ฒฐํฉํ์ฌ ์ฑ๋ฅ์ ๋์ฑ ์ต์ ํํ ์ ์์ต๋๋ค.
์์:
์ฌ์ฉ์์ ์ด๋ฆ์ ํ์ํ๋ ์ปดํฌ๋ํธ๊ฐ ์๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค.
import React, { useContext } from 'react';
import { UserContext } from './UserContext';
function UserName() {
const { user } = useContext(UserContext);
return ์ด๋ฆ: {user.name}
;
}
export default React.memo(UserName);
`UserName`์ `React.memo`๋ก ๋ํํ๋ฉด Context๋ฅผ ํตํด ์์์ ์ผ๋ก ์ ๋ฌ๋ `user` prop์ด ๋ณ๊ฒฝ๋๋ ๊ฒฝ์ฐ์๋ง ์ฌ๋ ๋๋ง๋ฉ๋๋ค. ๊ทธ๋ฌ๋ ์ด ๋จ์ํ ์์์๋ ์ ์ฒด `user` ๊ฐ์ฒด๊ฐ ์ฌ์ ํ prop์ผ๋ก ์ ๋ฌ๋๊ธฐ ๋๋ฌธ์ `React.memo`๋ง์ผ๋ก๋ ์ฌ๋ ๋๋ง์ ๋ฐฉ์งํ ์ ์์ต๋๋ค. ์ค์ ๋ก ํจ๊ณผ๋ฅผ ๋ฐํํ๋ ค๋ฉด ์ ํ๊ธฐ ํจ์ ๋๋ ๋ณ๋์ context์ ๊ฒฐํฉํด์ผ ํฉ๋๋ค.
๋ ํจ๊ณผ์ ์ธ ์๋ `React.memo`์ ์ ํ๊ธฐ ํจ์๋ฅผ ๊ฒฐํฉํฉ๋๋ค.
import React from 'react';
import { useUserName } from './UserHooks';
function UserName() {
const name = useUserName();
return ์ด๋ฆ: {name}
;
}
function areEqual(prevProps, nextProps) {
// ์ฌ์ฉ์ ์ง์ ๋น๊ต ํจ์
return prevProps.name === nextProps.name;
}
export default React.memo(UserName, areEqual);
์ฌ๊ธฐ์ `areEqual`์ `name` prop์ด ๋ณ๊ฒฝ๋์๋์ง ํ์ธํ๋ ์ฌ์ฉ์ ์ง์ ๋น๊ต ํจ์์ ๋๋ค. ๋ณ๊ฒฝ๋์ง ์์ ๊ฒฝ์ฐ ์ปดํฌ๋ํธ๋ ์ฌ๋ ๋๋ง๋์ง ์์ต๋๋ค.
์ฅ์ :
- prop ๋ณ๊ฒฝ ์ฌํญ์ ๋ฐ๋ผ ์ฌ๋ ๋๋ง์ ๋ฐฉ์งํฉ๋๋ค.
- ์์ ํจ์ํ ์ปดํฌ๋ํธ์ ์ฑ๋ฅ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค.
๋จ์ :
- prop ๋ณ๊ฒฝ ์ฌํญ์ ์ ์คํ๊ฒ ๊ณ ๋ คํด์ผ ํฉ๋๋ค.
- ์ปดํฌ๋ํธ๊ฐ ์์ฃผ ๋ณ๊ฒฝ๋๋ prop์ ์์ ํ๋ ๊ฒฝ์ฐ ๋ ํจ๊ณผ์ ์ผ ์ ์์ต๋๋ค.
- ๊ธฐ๋ณธ prop ๋น๊ต๋ ์์ต๋๋ค. ๋ณต์กํ ๊ฐ์ฒด์ ๊ฒฝ์ฐ ์ฌ์ฉ์ ์ง์ ๋น๊ต ํจ์๊ฐ ํ์ํ ์ ์์ต๋๋ค.
ํจํด 5: Context ๋ฐ Reducer(useReducer) ๊ฒฐํฉ
Context๋ฅผ useReducer
์ ๊ฒฐํฉํ๋ฉด ๋ณต์กํ ์ํ ๋
ผ๋ฆฌ๋ฅผ ๊ด๋ฆฌํ๊ณ ์ฌ๋ ๋๋ง์ ์ต์ ํํ ์ ์์ต๋๋ค. useReducer
๋ ์์ธก ๊ฐ๋ฅํ ์ํ ๊ด๋ฆฌ ํจํด์ ์ ๊ณตํ๋ฉฐ ์์
์ ๊ธฐ๋ฐ์ผ๋ก ์ํ๋ฅผ ์
๋ฐ์ดํธํ ์ ์์ผ๋ฏ๋ก Context๋ฅผ ํตํด ์ฌ๋ฌ ์ค์ ์ ํจ์๋ฅผ ์ ๋ฌํ ํ์๊ฐ ์ค์ด๋ญ๋๋ค.
์์:
import React, { createContext, useReducer, useContext } from 'react';
const UserContext = createContext(null);
const initialState = {
user: {
name: 'John Doe',
email: 'john.doe@example.com',
location: 'New York, USA'
},
theme: 'light',
language: 'en'
};
const reducer = (state, action) => {
switch (action.type) {
case 'UPDATE_USER':
return { ...state, user: { ...state.user, ...action.payload } };
case 'TOGGLE_THEME':
return { ...state, theme: state.theme === 'light' ? 'dark' : 'light' };
case 'SET_LANGUAGE':
return { ...state, language: action.payload };
default:
return state;
}
};
function UserProvider({ children }) {
const [state, dispatch] = useReducer(reducer, initialState);
return (
{children}
);
}
function useUserState() {
const { state } = useContext(UserContext);
return state.user;
}
function useUserDispatch() {
const { dispatch } = useContext(UserContext);
return dispatch;
}
export { UserContext, UserProvider, useUserState, useUserDispatch };
์ด์ ์ปดํฌ๋ํธ๋ ์ฌ์ฉ์ ์ง์ ํ ์ ์ฌ์ฉํ์ฌ ์ํ์ ์ก์ธ์คํ๊ณ ์์ ์ ๋์คํจ์นํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด:
import React from 'react';
import { useUserState, useUserDispatch } from './UserContext';
function UserProfile() {
const user = useUserState();
const dispatch = useUserDispatch();
const handleUpdateName = (e) => {
dispatch({ type: 'UPDATE_USER', payload: { name: e.target.value } });
};
return (
์ด๋ฆ: {user.name}
);
}
์ด ํจํด์ ๋ณด๋ค ๊ตฌ์กฐํ๋ ์ํ ๊ด๋ฆฌ ์ ๊ทผ ๋ฐฉ์์ ์ฅ๋ คํ๊ณ ๋ณต์กํ Context ๋ ผ๋ฆฌ๋ฅผ ๋จ์ํํ ์ ์์ต๋๋ค.
์ฅ์ :
- ์์ธก ๊ฐ๋ฅํ ์ ๋ฐ์ดํธ๋ฅผ ํตํ ์ค์ ์ง์ค์ ์ํ ๊ด๋ฆฌ.
- Context๋ฅผ ํตํด ์ฌ๋ฌ ์ค์ ์ ํจ์๋ฅผ ์ ๋ฌํ ํ์๊ฐ ์ค์ด๋ญ๋๋ค.
- ์ฝ๋ ๊ตฌ์ฑ ๋ฐ ์ ์ง ๊ด๋ฆฌ๊ฐ ํฅ์๋ฉ๋๋ค.
๋จ์ :
useReducer
ํ ๋ฐ reducer ํจ์์ ๋ํ ์ดํด๊ฐ ํ์ํฉ๋๋ค.- ๋จ์ํ ์ํ ๊ด๋ฆฌ ์๋๋ฆฌ์ค์์๋ ๊ณผ๋ํ ์ ์์ต๋๋ค.
ํจํด 6: ๋๊ด์ ์ ๋ฐ์ดํธ
๋๊ด์ ์ ๋ฐ์ดํธ๋ ์๋ฒ๊ฐ ํ์ธํ๊ธฐ ์ ์๋ ์์ ์ด ์ฑ๊ณตํ ๊ฒ์ฒ๋ผ ์ฆ์ UI๋ฅผ ์ ๋ฐ์ดํธํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค. ์ด๋ ํนํ ๋๊ธฐ ์๊ฐ์ด ๊ธด ์ํฉ์์ ์ฌ์ฉ์ ๊ฒฝํ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ ์ฌ์ ์ธ ์ค๋ฅ๋ฅผ ์ ์คํ๊ฒ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค.
์์:
์ฌ์ฉ์๊ฐ ๊ฒ์๋ฌผ์ ์ข์ํ ์ ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ํด ๋ณด์ญ์์ค. ๋๊ด์ ์ ๋ฐ์ดํธ๋ ์ฌ์ฉ์๊ฐ ์ข์์ ๋ฒํผ์ ํด๋ฆญํ ๋ ์ฆ์ ์ข์์ ์๋ฅผ ๋๋ฆฐ ๋ค์ ์๋ฒ ์์ฒญ์ด ์คํจํ๋ฉด ๋ณ๊ฒฝ ์ฌํญ์ ๋๋๋ฆฝ๋๋ค.
import React, { useContext, useState } from 'react';
import { UserContext } from './UserContext';
function LikeButton({ postId }) {
const { dispatch } = useContext(UserContext);
const [isLiking, setIsLiking] = useState(false);
const handleLike = async () => {
setIsLiking(true);
// ๋๊ด์ ์ผ๋ก ์ข์์ ์ ์
๋ฐ์ดํธ
dispatch({ type: 'INCREMENT_LIKES', payload: { postId } });
try {
// API ํธ์ถ ์๋ฎฌ๋ ์ด์
await new Promise(resolve => setTimeout(resolve, 500));
// API ํธ์ถ์ด ์ฑ๊ณตํ๋ฉด ์๋ฌด ์์
๋ ์ํํ์ง ์์ต๋๋ค(UI๊ฐ ์ด๋ฏธ ์
๋ฐ์ดํธ๋จ).
} catch (error) {
// API ํธ์ถ์ด ์คํจํ๋ฉด ๋๊ด์ ์
๋ฐ์ดํธ๋ฅผ ๋๋๋ฆฝ๋๋ค.
dispatch({ type: 'DECREMENT_LIKES', payload: { postId } });
alert('๊ฒ์๋ฌผ์ ์ข์ํ์ง ๋ชปํ์ต๋๋ค. ๋ค์ ์๋ํด์ฃผ์ธ์.');
} finally {
setIsLiking(false);
}
};
return (
);
}
์ด ์์ ์์ `INCREMENT_LIKES` ์์ ์ ์ฆ์ ๋์คํจ์น๋ ๋ค์ API ํธ์ถ์ด ์คํจํ๋ฉด ๋๋๋ ค์ง๋๋ค. ์ด๋ ๋ณด๋ค ๋ฐ์์ ์ธ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํฉ๋๋ค.
์ฅ์ :
- ์ฆ๊ฐ์ ์ธ ํผ๋๋ฐฑ์ ์ ๊ณตํ์ฌ ์ฌ์ฉ์ ๊ฒฝํ์ ํฅ์์ํต๋๋ค.
- ์ธ์ง๋ ๋๊ธฐ ์๊ฐ์ ์ค์ ๋๋ค.
๋จ์ :
- ๋๊ด์ ์ ๋ฐ์ดํธ๋ฅผ ๋๋๋ฆฌ๋ ค๋ฉด ์ ์คํ ์ค๋ฅ ์ฒ๋ฆฌ๊ฐ ํ์ํฉ๋๋ค.
- ์ค๋ฅ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ฒ๋ฆฌ๋์ง ์์ผ๋ฉด ๋ถ์ผ์น๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
์ ์ ํ ํจํด ์ ํ
๊ฐ์ฅ ์ ํฉํ Context Provider ํจํด์ ์ ํ๋ฆฌ์ผ์ด์ ์ ํน์ ์๊ตฌ ์ฌํญ์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค. ์ ํํ๋ ๋ฐ ๋์์ด ๋๋ ์์ฝ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
useMemo
๋ฅผ ์ฌ์ฉํ ๊ฐ ๋ฉ๋ชจ์ด์ ์ด์ : ์ข ์์ฑ์ด ์ ์ ๊ฐ๋จํ Context ๊ฐ์ ์ ํฉํฉ๋๋ค.- ์ฌ๋ฌ Context๋ฅผ ์ฌ์ฉํ ๊ด์ฌ์ฌ ๋ถ๋ฆฌ: Context์ ๊ด๋ จ ์๋ ์ํ ์กฐ๊ฐ์ด ํฌํจ๋ ๊ฒฝ์ฐ์ ์ด์์ ์ ๋๋ค.
- ์ฌ์ฉ์ ์ง์ ํ ์ ์ฌ์ฉํ ์ ํ๊ธฐ ํจ์: ์ปดํฌ๋ํธ์ ๋ช ๊ฐ์ง ์์ฑ๋ง ํ์ํ ํฐ Context ๊ฐ์ ๊ฐ์ฅ ์ ํฉํฉ๋๋ค.
React.memo
๋ฅผ ์ฌ์ฉํ ์ปดํฌ๋ํธ ๋ฉ๋ชจ์ด์ ์ด์ : Context์์ prop์ ์์ ํ๋ ์์ ํจ์ํ ์ปดํฌ๋ํธ์ ํจ๊ณผ์ ์ ๋๋ค.- Context ๋ฐ Reducer(
useReducer
) ๊ฒฐํฉ: ๋ณต์กํ ์ํ ๋ ผ๋ฆฌ ๋ฐ ์ค์ ์ง์ค์ ์ํ ๊ด๋ฆฌ์ ์ ํฉํฉ๋๋ค. - ๋๊ด์ ์ ๋ฐ์ดํธ: ๋๊ธฐ ์๊ฐ์ด ๊ธด ์๋๋ฆฌ์ค์์ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ๋ ๋ฐ ์ ์ฉํ์ง๋ง ์ ์คํ ์ค๋ฅ ์ฒ๋ฆฌ๊ฐ ํ์ํฉ๋๋ค.
Context ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํ ์ถ๊ฐ ํ
- ๋ถํ์ํ Context ์ ๋ฐ์ดํธ ๋ฐฉ์ง: ํ์ํ ๊ฒฝ์ฐ์๋ง Context ๊ฐ์ ์ ๋ฐ์ดํธํฉ๋๋ค.
- ๋ถ๋ณ ๋ฐ์ดํฐ ๊ตฌ์กฐ ์ฌ์ฉ: ๋ถ๋ณ์ฑ์ React๊ฐ ๋ณ๊ฒฝ ์ฌํญ์ ๋ณด๋ค ํจ์จ์ ์ผ๋ก ๊ฐ์งํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค.
- ์ ํ๋ฆฌ์ผ์ด์ ํ๋กํ์ผ๋ง: React DevTools๋ฅผ ์ฌ์ฉํ์ฌ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ ์๋ณํฉ๋๋ค.
- ๋์ ์ํ ๊ด๋ฆฌ ์๋ฃจ์ ๊ณ ๋ ค: ๋งค์ฐ ํฌ๊ณ ๋ณต์กํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฝ์ฐ Redux, Zustand ๋๋ Jotai์ ๊ฐ์ ๋ณด๋ค ๊ณ ๊ธ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ณ ๋ คํ์ญ์์ค.
๊ฒฐ๋ก
React Context API๋ ๊ฐ๋ ฅํ ๋๊ตฌ์ด์ง๋ง ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ํผํ๋ ค๋ฉด ์ด๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์ฌ์ฉํ๋ ๊ฒ์ด ํ์์ ์ ๋๋ค. ์ด ๋ฌธ์์์ ์ค๋ช ํ Context Provider ํจํด์ ์ดํดํ๊ณ ์ ์ฉํ๋ฉด ์ํ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌํ๊ณ , ์ฑ๋ฅ์ ์ต์ ํํ๋ฉฐ, ๋ณด๋ค ํจ์จ์ ์ด๊ณ ๋ฐ์์ฑ์ด ๋ฐ์ด๋ React ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค. ํน์ ์๊ตฌ ์ฌํญ์ ๋ถ์ํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์๊ตฌ ์ฌํญ์ ๊ฐ์ฅ ์ ํฉํ ํจํด์ ์ ํํ๋ ๊ฒ์ ์์ง ๋ง์ญ์์ค.
์ ๋ฐ์ ์ธ ๊ด์ ์ ๊ณ ๋ คํ์ฌ ๊ฐ๋ฐ์๋ ๋ํ ์ํ ๊ด๋ฆฌ ์๋ฃจ์ ์ด ์๋ก ๋ค๋ฅธ ์๊ฐ๋, ํตํ ํ์ ๋ฐ ์ง์ญ ๋ฐ์ดํฐ ์๊ตฌ ์ฌํญ์์ ์ํํ๊ฒ ์๋ํ๋์ง ํ์ธํด์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด Context ๋ด์ ๋ ์ง ์์ ์ง์ ํจ์๋ ์ฌ์ฉ์์ ๊ธฐ๋ณธ ์ค์ ์ด๋ ์์น์ ๋ฐ๋ผ ํ์งํ๋์ด ์ฌ์ฉ์๊ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ก์ธ์คํ๋ ์์น์ ๊ด๊ณ์์ด ์ผ๊ด๋๊ณ ์ ํํ ๋ ์ง ํ์๋ฅผ ๋ณด์ฅํด์ผ ํฉ๋๋ค.